#include"../Base.h"


EXTERN_C POBJECT_TYPE IoDriverObjectType;
EXTERN_C NTSTATUS
ObReferenceObjectByName(
    __in PUNICODE_STRING ObjectName,
    __in ULONG Attributes,
    __in_opt PACCESS_STATE AccessState,
    __in_opt ACCESS_MASK DesiredAccess,
    __in POBJECT_TYPE ObjectType,
    __in KPROCESSOR_MODE AccessMode,
    __inout_opt PVOID ParseContext,
    __out PVOID* Object
);

PDRIVER_OBJECT GetDriverObjectByName(PWCH name)
{
    UNICODE_STRING driverName;
    RtlInitUnicodeString(&driverName, name);
    PDRIVER_OBJECT pDriver = NULL;
    NTSTATUS status = ObReferenceObjectByName(&driverName, FILE_ALL_ACCESS, 0, 0, IoDriverObjectType, KernelMode, NULL, (PVOID *) & pDriver);
    if (NT_SUCCESS(status)) {
        ObDereferenceObject(pDriver);
    }
    return pDriver;
}



NTSTATUS DriverSelfDelete(PWCH path) {
	return ForceDeleteFile(path);
}


NTSTATUS DriverCleanRegistry(PUNICODE_STRING pReg) {

	NTSTATUS status = STATUS_UNSUCCESSFUL;

	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"DisplayName");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"ErrorControl");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"ImagePath");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"Start");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"Type");


	PWCH enumPath = (PWCH)ExAllocatePoolWithTag(PagedPool, pReg->MaximumLength + 0x100, 'yang');
	memset(enumPath, 0, pReg->MaximumLength + 0x100);
	memcpy(enumPath, pReg->Buffer, pReg->Length);
	wcscat(enumPath, L"\\Enum");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, enumPath, L"Count");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"INITSTARTFAILED");
	RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, pReg->Buffer, L"NextInstance");



	status = DeleteRegistryKey(enumPath);
	if (!NT_SUCCESS(status)) {
		LOG("删除enumKey失败\r\n");
		return status;
	}
	ExFreePoolWithTag(enumPath, 'yang');


	//删除根目录
	status = DeleteRegistryKey(pReg->Buffer);
	if (!NT_SUCCESS(status)) {
		LOG("删除rootKey失败\r\n");
	}

	return status;
}